package Controlador;

import Dao.DaoChofer;
import Dao.DaoCooperativa;
import Dao.DaoMulta;
import Dao.DaoRutaCoop;
import Dao.DaoRutas;
import Dao.DaoUnidadT;
import Dao.DaoViaje;
import Modelo.Chofer;
import Modelo.UnidadT;
import Modelo.Validaciones;
import Modelo.Viaje;
import Observer.AlarmaUnidadT;
import Observer.Fallas;
import Observer.NoDisponible;
import Vista.JFrameViajes;
import Vista.Mensajes;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ControladorViajes implements ActionListener, KeyListener {

    private JFrameViajes formViajes;
    private Viaje viaje;
    private boolean Existe;

    public ControladorViajes() 
    {
        
        formViajes = new JFrameViajes();
        formViajes.AgregarListener(this, this);
        formViajes.setVisible(true);
        AsignarCodigoViaje();

        Calendar fecha = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm aa");
        String formattedDate = dateFormat.format(new Date());
        formViajes.getHoraSalida().setText(formattedDate);
        
       AlarmaUnidadT alarma=new AlarmaUnidadT();
       
       alarma.addObservador(new Fallas());
       alarma.addObservador(new NoDisponible());        
    }

    //********************************************** 
    // Opciones de Botones    
    //***********************************************    
    @Override
    public void actionPerformed(ActionEvent e) {
        //---------------------------
        //Boton generar vehiculo
        //---------------------------
        if (e.getSource().equals(formViajes.getBtnGenerarVehiculo())) {
            if(formViajes.getDateFechaSalida().getDate() == null)
            {
                Mensajes.Aviso("Ingrese una fecha de salida", "");
                return;
            }
            GenerarVehiculo();
        }
        //boton Salir
        if (e.getSource().equals(formViajes.getBtnSalirV())) {
            formViajes.dispose();
        }
        if (e.getSource().equals(formViajes.getBtnGuardarV())) {
            GuardarViaje();
        }
        if (e.getSource().equals(formViajes.getBtnEliminarV())) {
            Limpiar();
        }

        if (e.getSource().equals(formViajes.getBtnBuscarV())) {
            new ControladorConsulViajes();
        }

        if (e.getSource().equals(formViajes.getCmbRutas())) {
            ComboRutas();
        }

        
    }

    @Override
    public void keyTyped(KeyEvent e) {
       if(e.getSource().equals(formViajes.getTxtCantidadPasV()))
       {
           PasajerosKeyTyped(e);
       }
    }

    @Override
    public void keyPressed(KeyEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void keyReleased(KeyEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

//------------------------------
    private void GenerarVehiculo()
    {
        try {
            Limpiar();
            int AleaVehi;
            int TamVehi;
            int AleaChofer;
            int TamChoferes;
            UnidadT unidad=new UnidadT();
            Chofer chofer = new Chofer();
            DaoUnidadT daoUnidad =  new DaoUnidadT();
            DaoChofer daoChofer =  new DaoChofer();
            DaoCooperativa daoCoop=new DaoCooperativa();
            DaoRutaCoop daoRC = new DaoRutaCoop();
            ResultSet rsVeh;
            ResultSet rsCho;
            ResultSet rsCoop;
            ResultSet rsRC;
            rsVeh = daoUnidad.CantidadUnidades();
            rsVeh.next();
            TamVehi = Integer.parseInt(rsVeh.getString(1));
            AleaVehi = Validaciones.Generar_Aleatorio(TamVehi);
            rsVeh= daoUnidad.ConsultarUnidadT();
            for(int i=0;i<=AleaVehi;i++)
            {
                rsVeh.next();
            }
            unidad.UnidadT(rsVeh.getString(1),
                           rsVeh.getString(2),
                           Integer.parseInt(rsVeh.getString(3)),
                           rsVeh.getString(4),
                           rsVeh.getString(5));
                        
            formViajes.getTxtPlacaVehV().setText(unidad.getPlaca());
            formViajes.getTxtCISocio().setText(unidad.getCISocio());
            
            rsCho= daoChofer.CantidadChofSocio(unidad.getCISocio());
            rsCho.next();
            TamChoferes= Integer.parseInt(rsCho.getString(1));
            AleaChofer= Validaciones.Generar_Aleatorio(TamChoferes);
            
            rsCho=daoChofer.BuscarChoferesSocio(rsVeh.getString(4));
            for(int i=0; i<=AleaChofer;i++)
            {
                rsCho.next();
            }
            
            formViajes.getTxtChofer().setText(rsCho.getString(1));
            
            int aleaCap = Validaciones.Generar_Aleatorio(unidad.getCapacidad());
            formViajes.getTxtCantidadPasV().setText(Integer.toString(aleaCap));
            formViajes.getTxtCodigoCoopV().setText(unidad.getCodCooperativa());
            
            rsCoop= daoCoop.BuscarCooperativa(unidad.getCodCooperativa());
            rsCoop.next();
            
            int seguro = unidad.getCapacidad()*Integer.parseInt(rsCoop.getString(5));
            formViajes.getTxtSeguro().setText(Integer.toString(seguro));
            //----------------------------------------------------------------
            // estos metodos se los agregue, para que mostrara la capacidad de los vehiculos
            // ambos funcionan bien, diganme cual es mejor o si no lo consideran necesario?
            formViajes.getjLabelMax().setText("Max:" + " " + unidad.getCapacidad()); // capacidad en un label
            formViajes.getTxtCantidadPasV().setToolTipText("Max:" + " " + unidad.getCapacidad()); // capacidad en un tooltiptext
            //----------------------------------------------------------------
            formViajes.getCmbRutas().removeAllItems();
            formViajes.getCmbRutas().addItem("Seleccione una Ruta");
            
            rsRC = daoRC.ConsultarRutasPorCoop(unidad.getCodCooperativa());
            
            while (rsRC.next())
            {
                String desRuta ="Codigo: "+rsRC.getString(1)+ " "+rsRC.getString(4);
                formViajes.getCmbRutas().addItem(desRuta);
                rsRC.next();
            }
            
            formViajes.getCmbRutas().setSelectedIndex(0);
        } catch (SQLException ex) {
            Logger.getLogger(ControladorViajes.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


//----------------------------------------------------------------
    // es necesario que al guardar los viajes, se registre el chofer que manejara 
    // dicha unidad. ya que para los reportes es necesario eso.
    private void GuardarViaje() {
        try {
            Viaje viaje = new Viaje();
            String Cadena;
            
            Cadena = formViajes.getTxtFechaLlegada().getText();
            if (Cadena.length() == 0) {
                Mensajes.Aviso("Fecha de llegada Vacia", "");
                formViajes.getTxtFechaLlegada().requestFocusInWindow();
                return;
            }
            
            
            Cadena = formViajes.getTxtCantidadPasV().getText();
            if (Cadena.length() == 0) {
                Mensajes.Aviso("Cantidad de pasajeros Vacia", "");
                formViajes.getTxtCantidadPasV().requestFocusInWindow();
                return;
            }
            int capacidad = 0;
            
            DaoUnidadT daoUnidad = new DaoUnidadT();
            ResultSet rsUnidad;
            rsUnidad = daoUnidad.BuscarUnidadT(formViajes.getTxtPlacaVehV().getText());
            rsUnidad.next();
            capacidad=Integer.parseInt(rsUnidad.getString(3));
            
            if (Integer.parseInt(Cadena) > capacidad) {
                Mensajes.Aviso("Cantidad de pasajeros excedida\n" + "Capacidad Máxima: " + capacidad, "");
                formViajes.getTxtCantidadPasV().requestFocusInWindow();
                return;
            }
            
            Cadena = formViajes.getCmbRutas().getSelectedItem().toString();
            if (Cadena.equals("Seleccione una Ruta")) {
                Mensajes.Aviso("Seleccione una Ruta", "");
                formViajes.getCmbRutas().requestFocusInWindow();
                return;
            }
            String dest = "";
            String[] dato;
            dato = Cadena.split(" ");
            for (int i = 2; i < dato.length; i++) {
                dest = dest + dato[i] + " ";
            }
            viaje.Viaje(formViajes.getCodViaje().getText(),
                    formViajes.getTxtPlacaVehV().getText(),
                    formViajes.getTxtCISocio().getText(),
                    formViajes.getTxtChofer().getText(),
                    formViajes.getTxtCodigoCoopV().getText(),
                    formViajes.getDateFechaSalida().getDate(),
                    formViajes.getHoraSalida().getText(),
                    dest,
                    Validaciones.CnvStringFecha(formViajes.getTxtFechaLlegada().getText()),
                    formViajes.getTxtHoraLLegadaV().getText(),
                    Integer.parseInt(formViajes.getTxtCantidadPasV().getText()),
                    Integer.parseInt(formViajes.getTxtSeguro().getText()),
                    'A');
            

            DaoViaje daoviaje=new DaoViaje();
            ResultSet rsVeDia = daoviaje.BuscarViajeVehDia(viaje.getPlacaVehiculo(), viaje.getFechaSalida());
            if(rsVeDia.next())
            {
                 Mensajes.Aviso("Este vehiculo ya fue asignado a este dia", Cadena);
                 Limpiar();
                 return;
            }
            DaoMulta daoMulta = new DaoMulta();
            ResultSet rsMulta;
            rsMulta=daoMulta.BuscarMultaporPlaca(viaje.getPlacaVehiculo());
            
            if(rsMulta.next())
            {
                rsMulta.next();
                Date diaMulta = Validaciones.CnvStringFecha2(rsMulta.getString(3));
                Date finMulta = Validaciones.sumarFechasDias(diaMulta, 3);
                if(viaje.getFechaSalida().compareTo(finMulta)<=0)
                {
                    Mensajes.Aviso("Este vehiculo esta multado", Cadena);
                    Limpiar();
                    return;
                }
                else
                {
                    daoviaje.IncluirViaje(viaje);
                    Mensajes.Aviso("Viaje registrado", "");
                    Limpiar();
                    AsignarCodigoViaje();
                    formViajes.getBtnBuscarV().requestFocusInWindow();
                }
            }
            else
            {
                daoviaje.IncluirViaje(viaje);
                Mensajes.Aviso("Viaje registrado", "");
                Limpiar();
                AsignarCodigoViaje();
                formViajes.getBtnBuscarV().requestFocusInWindow();
            }
            
        } catch (SQLException ex) {
            Logger.getLogger(ControladorViajes.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void ComboRutas() {
        if (formViajes.getCmbRutas().getSelectedIndex() > -1) {
            
            int dias, horas, min;
            Date fecha;
            String codRuta, dura;
            String datoRuta = formViajes.getCmbRutas().getSelectedItem().toString();
            codRuta = datoRuta.substring(8, 17);
            if (!datoRuta.equals("Seleccione una Ruta") & !datoRuta.equals("")) {
                try {
                    ResultSet rs;
                    DaoRutas daoRutas = new DaoRutas();
                    rs = daoRutas.BuscarRutas(codRuta);
                    rs.next();
                    
                    dura = rs.getString(5);
                    
                    dias = Integer.parseInt(dura.substring(0,2));
                    horas = Integer.parseInt(dura.substring(3,5));
                    min = Integer.parseInt(dura.substring(6,8));
                    SumarDuracionFecha(formViajes.getDateFechaSalida().getDate(),
                            formViajes.getHoraSalida().getText(),
                            dias, horas, min);
                } catch (SQLException ex) {
                    Logger.getLogger(ControladorViajes.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
                
            
        }
    }

    private void SumarDuracionFecha(Date fecha, String hora, int dias, int horas, int min) {

        String[] dato;
        String ampm, tokenHora;
        int d = 0, h = 0, m = 0;
        dato = hora.split(" ");
        ampm = dato[1];
        tokenHora = dato[0];
        dato = tokenHora.split(":");
        h = Integer.parseInt(dato[0]);
        m = Integer.parseInt(dato[1]);
        d = dias;
        if (min + m > 60) {
            m = min + m - 60;
            h = h + 1;
        } else {
            m = min + m;
        }
        if (horas <= 12) {
            if (h + horas > 12 & ampm.equals("PM")) {
                ampm = "AM";
                h = h + horas - 12;
                d = d + 1;
            } else if (h + horas > 12 & ampm.equals("AM")) {
                ampm = "AM";
                h = h + horas - 12;
            } else {
                h = h + horas;
            }
        } else if (horas > 12) {
            if (h + horas > 24 & ampm.equals("PM")) {
                ampm = "AM";
                h = h + horas - 24;
                d = d + 1;
            } else if (h + horas > 24 & ampm.equals("AM")) {
                ampm = "PM";
                h = h + horas - 24;
            } else {
                h = h + horas - 12;
            }

        }

        fecha = Validaciones.sumarFechasDias(formViajes.getDateFechaSalida().getDate(), d);
        DateFormat df = DateFormat.getDateInstance();
        String f = df.format(fecha);
        formViajes.getTxtFechaLlegada().setText(f);
        formViajes.getTxtHoraLLegadaV().setText(h + ":" + m + " " + ampm);
    }

    private void AsignarCodigoViaje() {
        DaoViaje daoviaje=new DaoViaje();
        int nroV=0;
        
        ResultSet rs = daoviaje.CantidadViajes();
        try {
            rs.next();
        } catch (SQLException ex) {
            Logger.getLogger(ControladorViajes.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            nroV = Integer.parseInt(rs.getString(1));
        } catch (SQLException ex) {
            Logger.getLogger(ControladorViajes.class.getName()).log(Level.SEVERE, null, ex);
        }
        nroV++;
        formViajes.getCodViaje().setText("V000" + nroV);
        
    }

    private void Limpiar() {
        formViajes.getTxtCISocio().setText("");
        formViajes.getTxtPlacaVehV().setText("");
        formViajes.getTxtCodigoCoopV().setText("");
        formViajes.getTxtCantidadPasV().setText("");
        formViajes.getTxtFechaLlegada().setText("");
        formViajes.getTxtHoraLLegadaV().setText("");
        formViajes.getCmbRutas().setSelectedIndex(-1);
        formViajes.getTxtChofer().setText("");
        formViajes.getjLabelMax().setText("");
        formViajes.getTxtSeguro().setText("");
        formViajes.getBtnBuscarV().requestFocusInWindow();
    }
    //-----------------------
   private void PasajerosKeyTyped(KeyEvent evt) {
        String Cadena;
        char Caracter;

        Cadena = formViajes.getTxtCantidadPasV().getText();
        if (Cadena.length() == 2) 
        {
            evt.consume();
        } else 
        {
            Caracter = evt.getKeyChar();

            if (Caracter == '.') {
                evt.consume();
            }

            if (Caracter < '0' || Caracter > '9') {
                evt.consume();
            }
        }

    }

}
